/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package xowl.gmi.controller;

/**
 *
 * @author Laurent WOUTERS
 */
public class Optional extends Element {
    protected xowl.gmi.model.cvssl.Optional definition;
    protected xowl.gmi.view.diagram.Optional widget;
    protected Element child;
    
    public Optional(Controller controller, Element parent, xowl.gmi.model.cvssl.Optional def) {
        super(controller, parent);
        this.definition = def;
        
        xowl.gmi.view.diagram.Optional.Actions actions = new xowl.gmi.view.diagram.Optional.Actions() {
            @Override public boolean acceptFlavor(java.awt.datatransfer.DataFlavor flavor) {
                return (flavor == Controller.flavorVariable || flavor == Controller.flavorASTNode);
            }
            @Override public boolean acceptData(java.awt.datatransfer.DataFlavor flavor, Object data) {
                if (flavor == Controller.flavorVariable) {
                    if (child != null)
                        return false;
                    xowl.gmi.model.cvssl.Variable var = (xowl.gmi.model.cvssl.Variable)data;
                    return (ASTMatcher.matches(definition.getElement(), var));
                } else if (flavor == Controller.flavorASTNode) {
                    if (child != null)
                        return false;
                    xowl.gmi.model.ast.ASTNode node = (xowl.gmi.model.ast.ASTNode)data;
                    xowl.gmi.model.cvssl.Variable var = (xowl.gmi.model.cvssl.Variable)node.getSymbol();
                    return (ASTMatcher.matches(definition.getElement(), var));
                }
                return false;
            }
            @Override public boolean drop(java.awt.datatransfer.DataFlavor flavor, Object data) {
                if (flavor == Controller.flavorVariable) {
                    if (child != null)
                        return false;
                    xowl.gmi.model.cvssl.Variable var = (xowl.gmi.model.cvssl.Variable)data;
                    actionAddVariable(var);
                    return true;
                } else if (flavor == Controller.flavorASTNode) {
                    if (child != null)
                        return false;
                    xowl.gmi.model.ast.ASTNode node = (xowl.gmi.model.ast.ASTNode)data;
                    actionAddNode(node);
                    return true;
                }
                return false;
            }
        };
        widget = new xowl.gmi.view.diagram.Optional(actions);
    }
    
    public void setChild(Element child) {
        this.child = child;
        this.widget.setChild(child.getWidget());
    }
    
    @Override public xowl.gmi.view.diagram.Widget getWidget() { return widget; }
    
    @Override protected int getContainedASTCount() {
        if (child == null)
            return 0;
        return child.getContainedASTCount();
    }
    @Override protected int getLeftSiblingsASTCount(Element divider) { return 0; }
    @Override protected boolean insertAST(xowl.gmi.model.ast.ASTNode node) {
        if (child != null)
            return child.insertAST(node);
        child = ASTMatcher.buildControlTree(controller, this, definition.getElement(), node, false);
        if (child == null)
            return false;
        widget.setChild(child.getWidget());
        controller.onDiagramUpdated();
        return true;
    }
    @Override protected ASTRemovalStatus removeAST(xowl.gmi.model.ast.ASTNode node) {
        if (child == null)
            return ASTRemovalStatus.NodeNotFound;
        ASTRemovalStatus value = child.removeAST(node);
        if (value != ASTRemovalStatus.NodeFound)
            return value;
        child.decommission();
        widget.setChild(null);
        child = null;
        controller.onDiagramUpdated();
        return ASTRemovalStatus.Done;
    }
    
    @Override public void saveTo(xowl.gmi.model.Diagram diagram) {
        if (child != null)
            child.saveTo(diagram);
    }
    @Override public void decommission() {
        if (child != null)
            child.decommission();
    }
}
